
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import Dict.*;
import java.io.FileOutputStream;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import org.omg.PortableServer.*;
import org.omg.PortableServer.POA;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author dtuanh
 */
public class DictionnaryImpl extends DictionnaryPOA {
    //le fichier de entry

    public static final String FILE_ENTRY = "./entries.dat";
    //le fichier de definition
    public static final String FILE_DEF = "./defs.dat";
    //liste de entity
    private static List ls_entity = new ArrayList();
    private Entity current = null;
    private ORB orb;
    POA theRootpoa;

    public DictionnaryImpl(POA theRootpoa) {
        this.theRootpoa = theRootpoa;
    }

    public void setORB(ORB orb_val) {
        orb = orb_val;
    }

    public void addEntity(String term, Dict.CategoryValue cat, Dict.PropertyType props, String def)
            throws Dict.TermExisted, Dict.CategoryAndPropsNotMatch {
        EntityImpl entity = new EntityImpl();
        WordImpl word = new WordImpl();


        word.setTerm(term);

        word.setCategory(cat);
        word.setProperty(props);
        entity.setDefinition(def);
        entity.setEntry(convert(word));
        ls_entity.add(convert(entity));

    }

    /**
     * Operation delEntity
     */
    public void delEntity(String term)
            throws Dict.TermNotFound {
        Entity entity = search(term);
        if (entity == null) {
            throw new TermNotFound();
        } else {
            this.ls_entity.remove(entity);
        }
    }

    /**
     * Operation modifDefinition
     */
    public void modifDefinition(String term, String newdef)
            throws Dict.TermNotFound {
        Entity entity = search(term);
        if (entity == null) {
            throw new TermNotFound();
        } else {
        EntityImpl entityImpl = new EntityImpl();
        entityImpl.setDefinition(newdef);
        entityImpl.setEntry(entity.myEntry());
        this.ls_entity.set(this.ls_entity.indexOf(entity), convert(entityImpl));
        }
    }

    /**
     * Operation findEntity
     */
    public Dict.Entity findEntity(String term)
            throws Dict.TermNotFound {
        Entity entity = search(term);
        if (entity == null) {
            throw new TermNotFound();
        }
        this.current = entity;
        return entity;
    }

    /**
     * Operation sortDict
     */
    public void sortDict(boolean dir) {
        for (int i = 0; i < ls_entity.size(); i++) {
            Entity e_i = (Entity)ls_entity.get(i);
            for (int j = i + 1; j < ls_entity.size(); j++) {
                Entity e_j = (Entity)ls_entity.get(j);
                // ascendant (terme) si direct = TRUE
                if (compare(e_i, e_j) > 0 && dir) {
                    ls_entity.set(j, e_i);
                    ls_entity.set(i, e_j);
                    e_i = (Entity)ls_entity.get(i);
                }
                //  descendant, DIRECT=FALSE
                if (compare(e_i, e_j) < 0 && !dir) {
                    ls_entity.set(j, e_i);
                    ls_entity.set(i, e_j);
                    e_i = (Entity)ls_entity.get(i);
                }
            }
        }
    }

    /**
     * Operation loadDict
     */
    public int loadDict()
            throws Dict.DicFileNotFound {
        System.out.println("Server is loading dict...");
        try {
            //lire les fichier de entry et de definition
            DataInputStream in_entry = new DataInputStream(new FileInputStream(FILE_ENTRY));
            DataInputStream in_def = new DataInputStream(new FileInputStream(FILE_DEF));
            String entry = null;
            String def = null;
            //supprimer le memoire
            ls_entity.clear();
            while (true) {
                entry = in_entry.readLine();
                def = in_def.readLine();
                if (entry == null || def == null) {
                    return ls_entity.size();
                }
                EntityImpl entity = new EntityImpl();

              

                Word word =
                        convert(DictionnaryTool.readWord(entry));
                entity.setDefinition(DictionnaryTool.readDefinition(def));
                entity.setEntry(word);
                Entity en = convert(entity);
                this.ls_entity.add(en);
            }



        } catch (IOException ex) {
            Logger.getLogger(DictionnaryImpl.class.getName()).log(Level.SEVERE, null, ex);
            throw new DicFileNotFound();
        }
    }

    /**
     * Operation saveDict
     */
    public void saveDict() {
        if (ls_entity.size() == 0) {
            return;
        }
        PrintWriter out_entry = null;
        PrintWriter out_def = null;
        try {
            out_entry = new PrintWriter(new FileOutputStream(FILE_ENTRY));
            out_def = new PrintWriter(new FileOutputStream(FILE_DEF));
            for (int i = 0; i < ls_entity.size(); i++) {
                Entity entity = (Entity) ls_entity.get(i);
                String txt_entity = "[" + i + "," + entity.myEntry().myCategory().toString() + "," + entity.myEntry().toFile() + "]";
                String txt_def = i + ",«" + entity.myDefinition() + "»";
                out_entry.println(txt_entity);
                out_def.println(txt_def);
            }
            out_entry.flush();
            out_def.flush();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(DictionnaryImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            out_entry.close();
        }
    }

    /**
     * Operation dictLength
     */
    public int dictLength() {
        return ls_entity.size();
    }

    /**
     * Operation firstEntity
     */
    public Dict.Entity firstEntity()
            throws Dict.DictEmpty {
       
        if (ls_entity.size() == 0) {
            throw new DictEmpty();
        }
       
        this.current = (Entity)ls_entity.get(0);
        return (Entity)ls_entity.get(0);
    }

    /**
     * Operation lastEntity
     */
    public Dict.Entity lastEntity()
            throws Dict.DictEmpty {
        if (ls_entity.size() == 0) {
            throw new DictEmpty();
        }
        this.current = (Entity)ls_entity.get(ls_entity.size() - 1);
        return (Entity)ls_entity.get(ls_entity.size() - 1);
    }

    /**
     * Operation nextEntity
     */
    public Dict.Entity nextEntity()
            throws Dict.DictEmpty {
        if (ls_entity.size() == 0) {
            throw new DictEmpty();
        }

        int index = currentIndex();
        if (index >= 0 && index < (ls_entity.size() - 1)) {
            current = (Entity)ls_entity.get(index + 1);
            return current;
        }

        return firstEntity();
    }

    /**
     * Operation prevEntity
     */
    public Dict.Entity prevEntity()
            throws Dict.DictEmpty {

        if (ls_entity.size() == 0) {
            throw new DictEmpty();
        }
        int index = currentIndex();
        if (index >= 1) {
            current = (Entity)ls_entity.get(index - 1);
            return (current);
        }

        return firstEntity();
    }

//chercher un entity
    private Entity search(String term) {
        for (int i = 0; i < ls_entity.size(); i++) {
            Entity entity = (Entity) ls_entity.get(i);
            if (entity.myEntry().myTerm().equalsIgnoreCase(term)) {

                return entity;
            }
        }
        return null;
    }

    //comparer entre deux mots
    int compare(Entity e1, Entity e2) {
        return e1.myEntry().myTerm().compareToIgnoreCase(e2.myEntry().myTerm());
    }

    //gerer l'entity actuel
    public int currentIndex() {
        for (int i = 0; i < ls_entity.size(); i++) {
            Entity tmp = (Entity) ls_entity.get(i);
            if (tmp == current) {
                return i;
            }
        }
        return -1;
    }

    public String echo(String message) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public String myDefinition() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    Entity convert(EntityImpl c_impl) {

        Entity unshared = null;
        try {
            byte[] oid = theRootpoa.activate_object(c_impl);
            unshared = EntityHelper.narrow(theRootpoa.id_to_reference(oid));
        } catch (Exception ex) {
        }
        return unshared;
    }
    Word convert(WordImpl c_impl) {

        Word unshared = null;
        try {
            byte[] oid = theRootpoa.activate_object(c_impl);
            unshared = WordHelper.narrow(theRootpoa.id_to_reference(oid));
        } catch (Exception ex) {
        }
        return unshared;
    }
}
